using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using XFABManager;

namespace XFGameFramework.EquipmentSystem
{

    [CustomEditor(typeof(EquipmentConfigData), true)]
    public class EquipmentConfigDataInspector : Editor
    {

        private static EquipmentConfigDataInspector _instance;

        public static EquipmentConfigDataInspector Instance
        {
            get
            {
                if (_instance == null)
                    _instance = CreateInstance<EquipmentConfigDataInspector>();
                return _instance;
            }
        }

        private EquipmentConfigData currentEquipmentConfigData;

        private EquipmentsConfig currentEquipmentsConfig;

        private SerializedObject currentSerializedObject;

        private List<SerializedProperty> currentSerializeProperty;

        private Vector2 currentPosition;
          
        private SerializedProperty script = null;

        public override void OnInspectorGUI()
        {
            EditorGUI.BeginDisabledGroup(true);

            base.OnInspectorGUI();

            EditorGUI.EndDisabledGroup();

            //if (GUILayout.Button("编辑装备"))
            //{
            //    ConfigsWindow window = EditorWindow.GetWindow<ConfigsWindow>();
            //    window.Show();
                 
            //    EquipmentsConfig current = null;

            //    foreach (var item in EquipmentsConfigController.GetAllEquipmentsConfig())
            //    {
            //        foreach (var skill in item.Equipments)
            //        {
            //            if (skill == target)
            //            {
            //                current = item;
            //                break;
            //            }
            //        }
            //        if (current != null)
            //            break;
            //    }
                 
            //    EquipmentConfigData currentSkill = target as EquipmentConfigData;
            //    string asset_path = AssetDatabase.GetAssetPath(current);
            //    ConfigsWindow.SelectGUID = AssetDatabase.AssetPathToGUID(asset_path); 
            //    window.SetSelection(currentSkill.id);
            //}
        }

        internal void OnInspectorGUI(ConfigsWindow window,EquipmentsConfig equipmentsConfig,EquipmentConfigData data )
        {
            this.currentEquipmentsConfig = equipmentsConfig;

            

            if (data != null)
            {

                if (currentEquipmentConfigData != data)
                {
                    currentEquipmentConfigData = data;
                    currentSerializedObject = null;   
                }

                if (currentSerializedObject == null)
                {
                    currentSerializedObject = new SerializedObject(currentEquipmentConfigData);
                    currentSerializeProperty = currentSerializedObject.GetAllSerializedProperty(); 
                    script = currentSerializedObject.FindProperty("m_Script"); 
                }

                currentSerializedObject.Update();
                currentPosition = GUILayout.BeginScrollView(currentPosition);
                
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.PropertyField(script);
                EditorGUI.EndDisabledGroup();

                for (int i = 0; i < currentSerializeProperty.Count; i++)
                {
                    SerializedProperty property = currentSerializeProperty[i];

                    if (property.name == "parent" && property.objectReferenceValue == null)
                    {
                        property.objectReferenceValue = equipmentsConfig;
                    }

                    if (GetPropertyCustomAttribute<HideInInspector>(property) != null) continue;
                    CustomPropertyGUI customPropertyGUI = GetPropertyCustomAttribute<CustomPropertyGUI>(property);
                    EditorGUI.BeginChangeCheck();

                    if (customPropertyGUI != null)
                    {
                        customPropertyGUI.OnPropertyGUI(property);
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(property);
                    }

                    if (EditorGUI.EndChangeCheck())
                    {
                        currentSerializedObject.ApplyModifiedProperties();

                        if (property.name == "id")
                            window.SetSelection(property.intValue);

                        //EditorUtility.SetDirty(currentEquipmentConfigData);

                        if (currentEquipmentConfigData.parent != null)
                            currentEquipmentConfigData.parent.ClearCache();

                        if (customPropertyGUI != null && customPropertyGUI.reloadTreeViewOnValueChange)
                            window.equipmentListTree.Reload();
                    }
                }

                GUILayout.EndScrollView();

                currentSerializedObject.ApplyModifiedProperties();
            }
            else
            {
                GUILayout.FlexibleSpace();
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUILayout.Label(string.Format("空!" ));
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();
            }
        }
           
        internal static Texture2D GetImage(string projectName, string assetName)
        {

            if (string.IsNullOrEmpty(projectName) || string.IsNullOrEmpty(assetName))
                return null;

            XFABProject project = XFABProjectManager.Instance.GetProject(projectName);

            if (project != null)
            {
                List<XFABAssetBundle> bundles = project.GetAllAssetBundles();

                foreach (var bundle in bundles)
                {
                    if (bundle == null)
                    {
                        continue;
                    }
                    string asset_path = bundle.GetAssetPathByFileName(assetName, typeof(Texture2D));

                    if (string.IsNullOrEmpty(asset_path))
                        asset_path = bundle.GetAssetPathByFileName(assetName, typeof(Sprite));

                    if (string.IsNullOrEmpty(asset_path))
                        continue;
                    Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(asset_path);
                    if (texture != null)
                        return texture;
                }
            }

            return null;
        }
         
        public static List<MonoScript> GetAllEquipmentsType()
        {
            List<MonoScript> states = new List<MonoScript>();

            string[] scripts = AssetDatabase.FindAssets("t:Script");

            foreach (var item in scripts)
            {
                string path = AssetDatabase.GUIDToAssetPath(item);
                MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);

                if (script == null) continue;

                Type type = script.GetClass();

                if (type == null) continue;

                if (type.IsSubclassOf(typeof(Component))) continue;

                if (typeof(IEquipment) == type) continue;

                if (typeof(IEquipment).IsAssignableFrom(type))
                    states.Add(script);
            }

            return states;
        }
         
        public static void OpenAsset(string guid)
        {
            if (string.IsNullOrEmpty(guid)) return;
            string asset_path = AssetDatabase.GUIDToAssetPath(guid);
            if (string.IsNullOrEmpty(asset_path)) return;
            AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath(asset_path, typeof(UnityEngine.Object)));
        }
         
        public static void SelectAsset(string guid)
        {
            if (string.IsNullOrEmpty(guid)) return;
            string asset_path = AssetDatabase.GUIDToAssetPath(guid);
            if (string.IsNullOrEmpty(asset_path)) return;

            UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(asset_path, typeof(UnityEngine.Object));
            Selection.activeObject = obj;
            EditorGUIUtility.PingObject(obj);
        }


        private Dictionary<SerializedProperty, Dictionary<Type, Attribute>> attributes = new Dictionary<SerializedProperty, Dictionary<Type, Attribute>>();

        private T GetPropertyCustomAttribute<T>(SerializedProperty property) where T : Attribute
        {
            if (!attributes.ContainsKey(property))
                attributes.Add(property, new Dictionary<Type, Attribute>());

            if (attributes[property].ContainsKey(typeof(T)))
                return attributes[property][typeof(T)] as T;

            Type type = property.serializedObject.targetObject.GetType();
            FieldInfo fieldInfo = type.GetField(property.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            T customPropertyGUI = fieldInfo.GetCustomAttribute<T>();

            attributes[property].Add(typeof(T), customPropertyGUI);
            return customPropertyGUI;
        }

    }

}

